Перейти к основному содержимому

7.07. Безопасность приложений

Разработчику Инженеру

Безопасность приложений

Безопасность фронтенда

Фронтенд — это первая линия обороны. Он взаимодействует с пользователем, поэтому особенно уязвим.

УгрозаРешение
XSS (Cross-site Scripting)Санитизация входных данных, применение Content Security Policy (CSP), использование современных фреймворков (React, Angular), экранирование всех динамически выводимых значений
CSRF (Cross-site Request Forgery)Использование CSRF-токенов, установка атрибута SameSite для cookies, корректная настройка CORS
ClickjackingЗаголовки X-Frame-Options (например, DENY или SAMEORIGIN) и директивы CSP (frame-ancestors)
Небезопасные скриптыИсключение подключения внешних JavaScript-библиотек из непроверенных или недоверенных источников
Утечка токенов авторизацииХранение токенов в защищённых cookie с атрибутами HttpOnly, Secure, SameSite=Strict или Lax; избегать использования localStorage
CORS политикиОграничение доменов, которым разрешено делать запросы к API, через заголовки Access-Control-Allow-Origin и другие CORS-заголовки
Произвольные скрипты и загрузка ресурсов из посторонних источниковНастройка Content Security Policy (CSP) для блокировки выполнения неавторизованных скриптов и загрузки ресурсов с недоверенных доменов

XSS (Cross-site Scripting) - это внедрение вредоносного кода на веб-страницу. Злоумышленник вставляет JS-скрипт, который выполняется в браузере жертвы. Может украсть токены, сессии, перенаправить пользователя.

Чтобы защититься от XSS, нужно экранировать всё, что выводится на страницу, использовать фреймворки, которые экранируют данные по умолчанию (React, Angular, Vue), добавить CSD, а также избегать использование innerHTML, eval() и dangerouslySetInnerHTML.

Санитизация - это очистка данных перед использованием или выводом. К примеру, Удаление потенциально опасных тегов (<script>, onerror, javascript:) из входящих данных. Используется при выводе пользовательского контента.

Content Security Policy (CSP) - это политика безопасности, ограничивающая выполнение скриптов. Браузер блокирует выполнение непроверенных скриптов и загрузку ресурсов со сторонних доменов. Помогает против XSS.

Escape всех выводимых значений - это экранирование специальных символов (<, >, & и др.). Предотвращает интерпретацию пользовательского ввода как HTML/JS. Например, «<b>» станет «<b>».

Clickjacking - это скрытое перехватывание действий пользователя. Злоумышленник встраивает ваш сайт в iframe и заманивает клики (например, «лайк», «войти»). Решается через X-Frame-Options и CSP.

CSRF токены - это случайные значения, проверяемые сервером. Сервер требует уникальный токен при POST-запросах, чтобы убедиться, что запрос отправил пользователь, а не злоумышленник.

SameSite-атрибуты cookies ограничивают отправку cookie в межсайтовых запросах. SameSite=Strict/Lax предотвращает автоматическую отправку токенов в запросах с других сайтов → защищает от CSRF.

CORS (Cross-Origin Resource Sharing) - политики доступа между доменами. Браузер блокирует запросы между разными доменами, если сервер не разрешил их явно. Защищает от несанкционированных API-вызовов.

Здесь важно отметить такие понятия, как origin и credentials.

Origin (источник) - это домен, с которого был сделан запрос. Например, Запрос из https://evil.com к https://bank.com имеет origin: https://evil.com.

Credentials (учётные данные) - это информация, которая может быть передана в запросе - куки, авторизованные заголовки, сертификаты клиента.

CORS-политики как раз работают с этими понятиями:

ПолитикаЧто делает
Access-Control-Allow-Origin: *Разрешает доступ к ресурсу со всех источников (доменов). При использовании значения * нельзя одновременно разрешать передачу учётных данных (credentials), так как это противоречит спецификации CORS.
Access-Control-Allow-Credentials: trueУказывает браузеру, что при запросе могут передаваться учётные данные (cookies, HTTP-аутентификация). Требует указания конкретного домена в Access-Control-Allow-Origin (значение * недопустимо).
withCredentials: trueФлаг в JavaScript (в объектах fetch или XMLHttpRequest), позволяющий включать учётные данные в кросс-доменные запросы. Работает только если сервер явно разрешает credentials через заголовок Access-Control-Allow-Credentials: true.

К примеру, в fetch API это будет так:

fetch('https://api.example.com/data',  {
method: 'GET',
credentials: 'include'
});

Небезопасный скрипт - внешние JS-файлы из непроверенных источников. Такие скрипты могут содержать вредоносный код. Лучше использовать CDN известных библиотек, а не случайные ссылки.

Непроверенный источник - использование внешних библиотек без верификации. Нужно проверять пакеты, использовать Snyk/Dependabot, не подключать JS/CSS с подозрительных сайтов.

Утечка токенов авторизации - сохранение токена в localStorage или URL. Токен можно украсть через XSS или историю браузера. Лучше хранить в httpOnly+secure cookie.

localStorage - это хранилище в браузере. Не защищено от XSS → не стоит хранить токены здесь. Подходит только для нечувствительной информации.

httpOnly - это атрибут cookie, запрещающий доступ из JavaScript. Предотвращает кражу токенов через XSS.

secure - это атрибут cookie, требующий HTTPS. Cookie будет передаваться только через защищённое соединение.

SameSite=Strict / Lax ограничивает отправку cookie в междоменных запросах. Strict: только свои домены. Lax: разрешает GET-запросы с других сайтов.

Strict - самый трогий режим SameSite. Cookie отправляются только при переходе внутри сайта.

Lax - более мягкий режим SameSite. Разрешает GET-запросы с других сайтов (например, ссылки).

Безопасность бэкенда

Бэкенд — «сердце» приложения. Здесь сосредоточена основная логика и доступ к данным.

УгрозаРешение
SQL InjectionИспользование ORM или параметризованных запросов для отделения кода от данных, исключающих выполнение произвольного SQL-кода.
Insecure Direct Object References (IDOR)Проверка прав доступа пользователя к запрашиваемому объекту перед его выдачей, независимо от переданного идентификатора.
Неправильная обработка ошибокИсключение вывода деталей стека, внутренних путей или конфигураций клиенту; использование обобщённых сообщений об ошибках в production.
Аутентификация и авторизацияПрименение стандартных протоколов (JWT, OAuth2, SAML), проверка ролей и прав, реализация моделей управления доступом (например, RBAC).
Rate LimitingОграничение количества запросов от одного клиента за определённый период для предотвращения атак типа brute-force и DDoS.
Валидация входных данныхСтрогая проверка всех входящих данных на соответствие ожидаемому формату, типу, диапазону и длине, включая фильтрацию потенциально опасных символов.
Подозрительная активностьПолное логирование действий пользователей, анализ аномалий, интеграция с системами SIEM для централизованного мониторинга и оповещения.
Обновление зависимостейРегулярный аудит используемых библиотек на наличие уязвимостей с помощью инструментов вроде Snyk, Dependabot или OWASP Dependency-Check.
Защита файловых загрузокПроверка MIME-типа, расширения, размера файла; сохранение файлов вне корневой директории сервера; изоляция исполняемого контекста.
Работа с сессиямиИспользование cookie с флагами HttpOnly, Secure, SameSite; короткий срок жизни сессионных токенов; регулярное обновление идентификаторов сессий.

Параметризованные запросы - это механизм работы с SQL-запросами, где пользовательские данные не встраиваются напрямую в SQL, а передаются отдельно. Это защита от SQL Injection (SQLi) — одной из самых опасных уязвимостей. Рекомендуется использовать ORM, и всегда использовать параметры вместо подстановки строк.

# ❌ Плохо: конкатенация
query = f"SELECT * FROM users WHERE id = {user_id}"

# ✅ Хорошо: параметризованный запрос
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))

IDOR (Insecure Direct Object Reference) - это уязвимость, при которой пользователь может получить доступ к ресурсам, к которым он не имеет прав, просто изменяя ID в URL или теле запроса.

Пример:

GET /api/user/123 → GET /api/user/456

Если сервер не проверяет права — можно получить чужие данные. Поэтому лучше проверять принадлежность объекта текущему пользователю, использовать UUID вместо числовых ID и логировать попытки несанкционированного доступа.

Stack traces (трассировки стека) - подробное описание ошибок, включая имя класса, метода, строки кода. Злоумышленник получает информацию о внутренней реализации, что помогает ему находить уязвимости. Для защиты нужно не показывать stack trace на боевых системах, использовать общие сообщения об ошибках: Internal Server Error, Access Denied, и логировать ошибки на сервере, но не отправлять детали клиенту.

Детали реализации - это любая информация, которая раскрывает технологическую реализацию : версии библиотек, пути, заголовки, сообщения об ошибках. Помогает злоумышленнику найти известные уязвимости в конкретных версиях ПО. Как защитить? Убирать заголовки типа Server, X-Powered-By. Не выводить информацию о технологиях в ответах. Использовать reverse proxy (Nginx, Traefik), чтобы скрыть backend.

Rate Limiting (Ограничение частоты запросов) - ограничение количества запросов от одного пользователя или IP за определённый период. Это защищает от брут-форса, DDoS и автоматизированных сканеров, выдавая «Too many requests».

DDoS (Distributed Denial of Service) - это атака, при которой сервер перегружается множеством запросов, чтобы сделать его недоступным. Множество устройств (ботнет) шлёт запросы на ваш сервер, сервер же не выдерживает нагрузку и падает. Чтобы от этого защититься, нужно использовать CDN (Cloudflare, AWS Shield), WAF (Web Application Firewall), Rate-limiting, облако с автоматическим масштабированием и конечно DDoS-защиту провайдера.

Brute-force атаки - это подбор логина/пароля, токена, ID и т.д. через массовые запросы. Встречается при авторизации, API с предсказуемыми ID, токенами восстановления пароля. Защита достигается через Rate limiting, CAPTCHA после нескольких неудачных попыток, двухфакторную авторизацию (MFA) и невозможность угадать токен (если использовать случайные значения).

CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) — это тест, который позволяет отличить человека от бота. Используется для защиты от автоматизированных действий: регистрации, авторизации, отправки форм и т.д.

Типы CAPTCHA:

  • Text CAPTCHA - ввод текста с искажённого изображения
  • reCAPTCHA v2 / v3 - Google reCAPTCHA («Я не робот», Invisible CAPTCHA)
  • hCaptcha - альтернатива reCAPTCHA
  • Checkbox CAPTCHA - простая галочка «Я не робот»
  • No CAPTCHA - поведенческий анализ (reCAPTCHA v3)

CAPTCHA, конечно, не защищает от продвинутых ботов, иногда требует JS или куки, а также может мешать UX.

Валидация входных данных - это проверка всех входящих данных на корректность, безопасность и допустимые значения. Это строгая валидация типов (isEmail, isInt), очистка и нормализация данных, использование специальных библиотек.

Strict validation (строгая валидация) - это не просто «что-то пришло», а проверка точного формата, типа и диапазона значений. Это предотвращает подмену данных, упрощает тестирование и защищает от непредвиденных ситуаций.

Подозрительная активность - это необычное поведение: много запросов, попытки подобрать ID, странная геолокация, нестандартные User-Agent'ы и т.д. Мониторить её нужно, чтобы выявлять возможные атаки, предотвращать инсайдерские угрозы и отслеживать утечки учётных записей. Используется через логирование всех действий, интеграцию с SIEM и настройку алертов (например, на 10+ неудачных авторизаций.

SIEM (Security Information and Event Management) - это система сбора, анализа и реагирования на события безопасности. Нужно для централизованного логирования, обнаружения аномалий, аудита действий пользователей, реагирования на инциденты.

Обновление зависимостей - это регулярная проверка и обновление библиотек, фреймворков и компонентов. Большинство уязвимостей - в зависимостях. Защититься можно через автоматические проверки, CI/CD интеграцию и сканеры SCA.

Software Composition Analysis (SCA) — это процесс анализа зависимостей в проекте с целью выявления уязвимостей, лицензионных проблем и устаревших компонентов. Современные приложения используют сотни и тысячи open-source библиотек . Если они содержат уязвимости — ваше приложение тоже уязвимо.

SCA-инструменты - это:

  • Snyk;
  • Dependabot;
  • OWASP Dependency Check;
  • Sonatype Nexus IQ;
  • WhiteSource / BlackDuck.

Snyk - это инструмент для поиска уязвимостей в зависимости и контейнерах. Он позволяет выполнять поиск CVE в npm, pip, Maven и т.д., позволяет интегрироваться с GitHub, CI/CD, предлагает патчи.

CVE (Common Vulnerabilities and Exposures) — это стандартизированный список известных уязвимостей в программном обеспечении. Каждой уязвимости присваивается уникальный идентификатор вида CVE-YYYY-XXXXX.

CVSS — Common Vulnerability Scoring System - это оценка уязвимости от 0 до 10, где 9-10 критическая, 7-8.9 высокая, 4-6.9 средняя, 0-3.9 низкая.

Dependabot - это интеграция в GitHub, которая автоматически обновляет зависимости и сообщает о уязвимостях. Поддерживает Docker, NuGet, Composer, позволяет обновлять package.json, requirements.txt и прочее.

webroot - это корневая директория сайта, откуда отдаются файлы. Нельзя выходить выше webroot, а в этой директории не нужно хранить чувствительные файлы (.env, .git, config.php и т.д.). Для защиты лучше не давать возможность листинга директорий, переносить чувствительные файлы вне папки webroot и использовать .htaccess / nginx.conf для ограничений.

Cookie-флаги - это настройки cookie, которые делают их более безопасными.

  • HttpOnly запрещает чтение cookie из JS → защищает от XSS;
  • Secure передаёт Cookie только через HTTPS;
  • SameSite=Strict/Lax ограничивает отправку cookie в междоменных запросах;
  • Max-Age / Expires устанавливает время жизни;
  • Path / Domain ограничивает область действия.

Что важно добавить в проект для безопасности

Что важно добавить в проект для безопасности?

КомпонентЧто добавить
СерверНастройка HTTPS, использование WAF (Web Application Firewall), конфигурация файрвола, rate limiting, мониторинг состояния системы, централизованное логирование
APIРеализация авторизации, принцип наименьших привилегий, строгая валидация входных данных, ограничение частоты запросов, поддержка актуальной документации (например, OpenAPI)
База данныхШифрование данных (в покое и в движении), выдача минимально необходимых привилегий, защита от SQL-инъекций, регулярное резервное копирование и проверка восстановления
АвторизацияПоддержка MFA, использование безопасных токенов (JWT/OAuth2), механизм refresh-токенов, реализация выхода из системы, политика сложных паролей
Файлы и загрузкиПроверка типа и расширения файлов, изоляция среды хранения, ограничение размера загрузки, сканирование на вирусы и вредоносный код
Пользовательский вводСанитизация и нормализация данных, строгая валидация, экранирование выводимого контента, применение Content Security Policy (CSP)
Сервисы и зависимостиИспользование актуальных версий библиотек, анализ состава ПО (SCA), автоматическое отслеживание уязвимостей, регулярные обновления
CI/CDИнтеграция анализа уязвимостей (SAST, SCA), автоматизированное тестирование безопасности, проверка конфигураций, сборка в изолированной среде
Работа с даннымиМинимизация объёма собираемых данных, шифрование конфиденциальной информации, соблюдение сроков хранения, безопасное удаление устаревших данных
ИнцидентыРазработка и поддержка плана реагирования на инциденты, процедуры уведомления пользователей и регуляторов, взаимодействие с CERT и другими организациями по кибербезопасности

WAF (Web Application Firewall) — это специализированный файрвол для защиты веб-приложений от атак уровня приложения (например, XSS, SQLi, CSRF). Анализирует HTTP-запросы, блокирует подозрительные запросы до того, как они достигнут бэкенда. Может быть облачным (Cloudflare, AWS WAF) или локальным (ModSecurity).

Файрвол — это система фильтрации сетевого трафика на уровне IP/портов. Stateful firewall отслеживает состояние соединений, Stateless firewall работает с правилами без учёта состояния, а Application Layer Firewall обеспечивает фильтрацию на уровне приложения (WAF чаще всего).

Входящий трафик → проверяется правилами → пропускается или блокируется

Минимальные привилегии (Principle of Least Privilege) подразумевают, что каждый пользователь, процесс или сервис должен иметь минимально возможные права, чтобы выполнять свою задачу. Всегда лучше «недодать», чем «переборщить». Это предотвратит распространение угроз внутри системы, несанкционированный доступ и утечки данных. К примеру. пользователь не может удалять таблицы, сервис запускается без прав root, а администратор не имеет доступа ко всем данным.

RBAC (Role-Based Access Control) - это ролевое управление доступом, где доступ к данным и функциям зависит от роли пользователя.

ABAC (Attribute-Based Access Control) - это атрибут-ориентированное управление доступом, где доступ зависит от характеристик (атрибутов) пользователя, объекта и среды.

IAM (Identity and Access Management) - это система управления удостоверениями и правами доступа . Она обеспечивает аутентификацию (кто ты), авторизацию (что ты можешь) и аудит (что ты сделал).

Refresh tokens - это токены, используемые для обновления короткоживущих access токенов, чтобы не требовать повторного входа пользователя.

Login → получаем short-lived access token + long-lived refresh token
Когда access истекает → отправляем refresh → получаем новый access

Важно: если утекает refresh token → злоумышленник может получить доступ на долгое время.

Экранирование (Escaping) - это преобразование специальных символов в безопасную форму, чтобы они не интерпретировались как код. Используется для безопасного вывода HTML/JS и санитизации входных данных, а также для предотвращения XSS.

Минимизация сбора подразумевает не собирать больше, чем необходимо. Это один из принципов GDPR, CCPA и других регуляций. К примеру, не собирать номер паспорта, если он не нужен, не хранить пароли в открытом виде и удалять данные после окончания их жизненного цикла. Это снижает риск утечки, соответствует законодательству и упрощает управление данными.

GDPR (General Data Protection Regulation) - это европейский закон о защите персональных данных, действует с 2018 года . Регулирует сбор, обработку и хранение персональной информации граждан ЕС.

Принципы:

  • Данные можно собирать только с согласия пользователя;
  • Пользователь может потребовать удалить свои данные;
  • Пользователь может запросить выгрузку своих данных;
  • В случае утечки — уведомить регулятора в течение 72 часов;
  • Собирать только то, что необходимо;
  • Назначается при определённых объемах обработки.

Американский аналог GDPR, CCPA (California Consumer Privacy Act) действует в Калифорнии с 2020 года. Защищает права жителей штата на контроль над своими данными.

Основные положения:

  • Пользователь может узнать, какие данные собираются;
  • Пользователь может попросить удалить его данные;
  • Запрет на продажу персональных данных без согласия;
  • Нельзя наказывать пользователей за использование прав.

В РФ нет полного аналога GDPR или CCPA, но есть базовые права и Федеральный закон №152-ФЗ «О персональных данных».

Основные положения:

  • персональные данные - это любая информация, относящаяся к определённому физическому лицу (ФИО, телефон, email, ИНН и т.д.);
  • согласие на обработку обязательно, если только данные не попадают под исключения (например, публичные данные);
  • оператор персональных данных - это организация или ИП, которые собирают и обрабатывают персональные данные;
  • с 2015 года российские пользователи должны иметь свои данные, сохранённые на серверах в РФ;
  • нет обязательного требования на уведомление об утечке;
  • субъект персональных данных имеет право на доступ, исправление и удаление своих данных.

Безопасность в разных языках

Что важно учесть при настройке безопасности в разных языках?

ЯзыкОсобенности безопасности
JavaScript (Node.js)Использование Helmet для безопасных HTTP-заголовков, sanitize-html для очистки HTML, cors и helmet-csp для управления политиками; избегать eval() и других функций с динамическим выполнением; контроль зависимостей в npm на наличие уязвимостей
Python (Django, Flask)Django предоставляет встроенную защиту от XSS и CSRF; в Flask необходимо подключать защиту вручную; использовать python-dotenv для управления конфигурацией; проверка pip-пакетов на уязвимости через инструменты вроде safety или bandit
Java (Spring Boot)Применение Spring Security для аутентификации и авторизации; использование OWASP Dependency-Check для анализа уязвимостей в зависимостях; генерация криптографически стойких случайных значений через SecureRandom; работа с шифрованием через Java Cryptography Architecture (JCA)
PHPИспользование PDO с подготовленными выражениями вместо устаревших mysql_* функций; хеширование паролей через password_hash(); экранирование вывода с помощью htmlspecialchars(); ограничение доступа через .htaccess
Ruby (Ruby on Rails)Встроенная защита от XSS и CSRF; использование strong parameters для фильтрации входных данных; автоматическое экранирование вывода в шаблонах
GoРабота с безопасностью на уровне middleware в net/http; использование параметризованных запросов через sql.DB; применение стандартного пакета crypto/* для шифрования; реализация собственных механизмов защиты при необходимости
C# (.NET Core)Использование ASP.NET Identity для управления пользователями; Data Protection API для шифрования данных; Anti-Forgery Tokens для защиты от CSRF; Entity Framework с параметризованными запросами снижает риски SQL-инъекций
RustВысокий уровень контроля за памятью и безопасность на этапе компиляции; отсутствие типичных уязвимостей, связанных с переполнением буфера; рекомендуется использовать проверенные и безопасные crates из crates.io

Helmet - библиотека для Node.js, которая устанавливает важные HTTP-заголовки безопасности.

sanitize-html - библиотека в JavaScript для очистки HTML от небезопасных тегов и скриптов.

eval() - функция в JavaScript, которая выполняет строку как код. Рекомендуется её никогда не использовать, а при необходимости для JSON применять JSON.parse(). В идеале нужно санитизировать всё, что попадает в eval, если без него не обойтись.

npm-пакет - это библиотеки, доступные через npm (Node Package Manager). Многие пакеты содержат уязвимости, поэтому лучше проветь CVE. Кроме того, важно отметить ещё одну вещь. Пакеты могут быть компрометированы (dependency confusion, typosquatting).

Dependency Confusion - это когда злоумышленник публикует пакет с таким же названием, как у внутреннего приватного пакета, но с более высокой версией. При установке зависимостей система может выбрать вредоносный пакет вместо нужного. К примеру, проект использует mycompany-utils@1.0.0 (приватный), а злоумышленник публикует mycompany-utils@1.0.1 в npm / PyPI / NuGet. При установке зависимостей — загружается вредоносный пакет. Чтобы защититься, лучше проверять зависимости, не использовать пакеты с подозрительными именами. Как правило, IDE сейчас предупреждают, что пакеты сомнительные.

Typosquatting - это когда злоумышленник публикует пакет с похожим именем на популярную библиотеку, чтобы разработчики ошиблись и установили его. К примеру, вы хотели установить requests, но набрали request → получили вредоносный пакет. Чтобы защититься, нужно следить за опечатками при установке, проверять рейтинги и количество загрузок, использовать инструменты для проверки пакетов.

python-dotenv - инструмент для загрузки переменных окружения из файла .env. В Git важно не коммитить этот файл, используя .gitignore. Это файл для хранения чувствительной информации вне кода для удобства настройки разных сред (dev, prod).

pip-пакеты - это Python-библиотеки, установленные через pip. Уязвимые версии пакетов могут вызвать проблемы, и иногда пакеты могут содержать вредоносный код. Существуют специальные команды вроде pip-audit, audit, snyk test --python для проверки.

Spring Security - это платформа Spring для реализации аутентификации, авторизации и защиты веб-приложений.

OWASP Dependency-Check - это инструмент для анализа зависимостей и поиска известных уязвимостей (CVE). Может использоваться в разных системах, запускается через dependency-check.sh.

SecureRandom - это класс в Java для генерации криптографически безопасных случайных чисел. Его можно использовать для генерации токенов, паролей, солей. Math.random() предсказуем и не подходит для генерации такой информации.

Соль (salt) - это случайная строка, добавляемая к паролю перед хэшированием, чтобы сделать одинаковые пароли уникальными.

Пример:

String password = "password123";
String salt = generateSecureSalt(); // SecureRandom
String hashed = hashWithSalt(password, salt);

Java Cryptography Architecture (JCA) - это API Java для шифрования, подписей, хэширования и других криптографических операций. PDO - это PHP Data Objects для работы с БД, поддерживающие параметризованные запросы. Защищает от SQLi, поддерживает разные СУБД. ASP.NET Identity - это фреймворк Microsoft для управления пользователями, аутентификацией и авторизацией.

IdentityServer — это фреймворк для реализации аутентификации и авторизации в .NET , поддерживающий стандарты OAuth 2.0, OpenID Connect (OIDC), SAML. Используется для выдачи токенов, проверки подлинности, управления клиентами и ресурсами.

Anti-Forgery Tokens - это механизм защиты от CSRF-атак в ASP.NET. Сервер генерирует уникальный токен. Клиент должен отправить его обратно при POST-запросах.

Forgery — это попытка подделки запроса от имени пользователя, например, через CSRF (Cross-Site Request Forgery). Антифорджери токен как раз обеспечивает генерацию уникального токена для отправки вместе с запросом. Если токена нет или он неверен, запрос блокируется.

Низкоуровневый контроль подразумевает работу с памятью, буферами, указателями, это особенно актуально в языках вроде C/C++, Rust, Go. Именно такой контроль отвечает за переполнение буфера, чтение данных из чужой области памяти, использование небезопасных блоков. Для слежения за буферами нужно использовать безопасные методы работы с данными, языки с защитой от переполнения (Rust, Go), валидировать размеры входящих данных.

«Safe» крейты в Rust — библиотеки, написанные на безопасном Rust, без использования unsafe блоков.

Защита API

Как защитить API?

  1. Ограничение частоты запросов (Rate Limiting) подразумевает жёсткое ограничение на количество запросов в единицу времени. Если лимит превышается — клиент получает ошибку 429 Too Many Requests. К примеру, максимум 1000 запросов в час.

Реализовать можно через Redis+middleware, Nginx limit_req_zone и API Gateway (AWS, Kong, Tyk).

API Gateway - это сервис, который выступает единым входом для всех ваших микросервисов или API, обеспечивая аутентификацию, авторизацию, rate limiting, логирование, трансформацию запросов и кэширование.

Популярные решения API Gateway:

РешениеВозможности
AWS API GatewayПолностью управляемый сервис от Amazon Web Services для создания, публикации и управления API; встроенные функции аутентификации, авторизации, мониторинга, rate limiting и интеграции с Lambda
KongОткрытый API-шлюз на основе NGINX с поддержкой плагинов: аутентификация (JWT, OAuth2), ограничение частоты запросов, логирование, трансформация запросов; масштабируемость и расширяемость
TykOpen-source API Gateway с возможностью использования в составе enterprise-платформы; поддержка rate limiting, аналитики, JWT, OAuth2, webhook-триггеров и централизованного управления через dashboard
Azure API ManagementУправляемое решение Microsoft для публикации, защиты, анализа и масштабирования API; интеграция с Azure Active Directory, политиками преобразования и шифрования, SLA-гарантии
TraefikСовременный reverse proxy и API Gateway с поддержкой микросервисов; автоматическое обнаружение сервисов (через Docker, Kubernetes и др.); встроенные функции балансировки, TLS, middleware для аутентификации и rate limiting
NGINX PlusКоммерческая версия NGINX с расширенными возможностями: продвинутое управление трафиком, rate limiting, JWT-аутентификация, мониторинг, поддержка gRPC и WebSocket

Redis + middleware (Node.js, Python, Go) подразумевает использование Redis как хранилища для отслеживания количества запросов от клиента. Middleware проверяет лимиты перед выполнением обработки.

Nginx limit_req_zone - это модуль Nginx, позволяющий ограничивать частоту запросов на уровне reverse proxy / load balancer.

  1. Троттлинг (Throttling) - мягкая форма контроля частоты запросов. Если клиент выходит за пределы нормального поведения — его запросы замедляются, но не блокируются полностью. Пример:
    • До 500 запросов в минуту – нормально;
    • Более 500 – замедление ответа;
    • Более 1000 – блокировка.

Это более гибкий контроль нагрузки, и реализуется через алгоритмы Token Bucket, Leaky Bucket, Redis+очередь и API Gateway.

Token Bucket («Ведро с токенами») работает так:

  • В «ведре» есть определённое число токенов;
  • На каждый запрос забирается один токен;
  • Если токенов нет → отказ;
  • Ведро наполняется со временем.

Leaky Bucket («Протекающее ведро»):

  • Запросы ставятся в очередь (ведро)
  • Ведро «протекает» с фиксированной скоростью
  • Если очередь заполнена → запросы отбрасываются
  1. Инструменты мониторинга. Это системы, которые собирают метрики, логи и события из API, чтобы обнаруживать аномалии и реагировать на инциденты.
ИнструментВозможности
DatadogКомплексный платформенный инструмент для сбора метрик, логов, трассировки (APM), мониторинга безопасности (SIEM) и анализа производительности приложений
AWS CloudWatchУправляемый сервис AWS для сбора метрик, логов и установки оповещений в рамках облачной инфраструктуры Amazon
Prometheus + GrafanaPrometheus — система сбора и хранения временных рядов; Grafana — визуализация метрик. Используется для мониторинга микросервисов и инфраструктуры
ELK Stack (Elasticsearch, Logstash, Kibana)Решение для централизованного сбора, индексации и анализа логов: Logstash — агрегация, Elasticsearch — хранение и поиск, Kibana — визуализация
Grafana LokiЛёгковесная система сбора и хранения логов, оптимизированная для интеграции с Grafana и работы с метками (labels), без индексации содержимого логов
New RelicПлатформа для мониторинга производительности приложений (APM), обнаружения ошибок, анализа безопасности и отслеживания пользовательского поведения

Как использовать мониторинг для безопасности?

  • Отслеживание аномальных запросов (например, много 4xx);
  • Обнаружение DDoS по пикам нагрузки;
  • Выявление подозрительных IP или пользователей;
  • Логирование всех действий с возможностью поиска.
  1. Сложные ID (UUID вместо числовых ID). Вместо простых числовых ID (/user/1, /order/2) использовать уникальные и непредсказуемые значения, например:
/user/6ba7b810-9dad-11d1-80b4-00c04fd430c8

Это предотвратит IDOR, скроет структуру системы от злоумышленников и уменьшит возможность перебора. Для реализации надо генерировать UUID v4 при создании объекта, использовать их как первичные ключи или внешние идентификаторы.

  1. Ограничение доступа к API и контроллерам. Это контроль того, кто может вызывать определённые эндпоинты и как часто. Существуют следующие практики:
ТехникаОписание
RBAC / ABACМодели управления доступом: ролевая (RBAC — на основе ролей) и атрибутная (ABAC — на основе набора атрибутов пользователя, ресурса и контекста)
API KeysКлючи для идентификации и авторизации клиентских приложений; требуют безопасного хранения и регулярной ротации
JWT / OAuth2Стандарты токенов: JWT содержит подписанные данные (включая роль и срок действия), OAuth2 — протокол делегирования авторизации
IP WhitelistingОграничение доступа к API только с доверенных IP-адресов или диапазонов
Scope-based accessПредоставление доступа к ресурсам в соответствии с областью (scope), например, read:users, write:documents
WAFWeb Application Firewall фильтрует входящий трафик, блокируя запросы, содержащие признаки атак (XSS, SQLi, сканирование и др.)
  1. Другие способы защиты API.
МераОписание
HTTPSВсе HTTP-запросы должны передаваться по зашифрованному каналу TLS
CORS политикиНастройка заголовков Access-Control-Allow-Origin и других CORS-атрибутов для разрешения запросов только с доверённых доменов
Authentication & AuthorizationРеализация механизмов аутентификации (JWT, OAuth2, API Keys) и проверки прав доступа
Валидация входных данныхПроверка всех входящих данных на соответствие формату, типу и диапазону значений
Экранирование выводаПреобразование специальных символов для предотвращения выполнения произвольного кода (например, XSS)
Проверка заголовков и параметровИсключение передачи конфиденциальной информации через URL-параметры или незащищённые заголовки
Логирование и аудитФиксация всех значимых операций с возможностью последующего анализа и расследования инцидентов
Rate limiting + ThrottlingОграничение количества запросов от одного клиента для защиты от brute-force и DDoS-атак
Обновление зависимостейРегулярный аудит библиотек с помощью Snyk, Dependabot и аналогичных инструментов
Интеграция с WAFРазмещение WAF перед API для фильтрации вредоносного трафика на границе сети
Работа с токенамиИспользование безопасных cookie-флагов (HttpOnly, Secure, SameSite), короткий TTL для access-токенов, использование refresh-токенов
Rate limiting по IP / User-Agent / TokenМногоуровневое ограничение частоты запросов на основе различных идентификаторов
Географические ограниченияБлокировка или дополнительная верификация запросов из регионов, где сервис официально не используется

Как выглядит защищённый API-запрос?

GET /api/users/me HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
User-Agent: MyApp/1.0
Accept: application/json
Origin: https://trusted-origin.com

На сервере проверяется токен, проверяется origin через CORS, логируется запрос, проверяется rate limit, права доступа, а ответ шифруется через HTTPS.